// Package id
// Title 			snowflake.id.components.go
// Description 		雪花处理组件
// Author  			alittlexincan@163.com 					2024/07/22 11:36
// Update  			alittlexincan@163.com 					2024/07/22 11:36
package id

import (
	"sync"
	"time"

	"github.com/bwmarrin/snowflake"
	"go.uber.org/zap"
	"xincan.com.cn/tarot-go/internal/common/types"
	"xincan.com.cn/tarot-go/internal/components/logging"
)

// snowflakeIdComponent
// Title snowflakeIdComponent
// Description 		雪花ID组件
// Author  			alittlexincan@163.com 								2024/07/22 11:36
// Update  			alittlexincan@163.com 								2024/07/22 11:36
type snowflakeIdComponent struct {
	nodeId   int64                // 节点ID
	logger   *logging.TraceLogger // 日志组件
	instance *snowflake.Node      // 雪花ID组件实例
	once     sync.Once            // 单例
}

// SnowflakeIdComponentBuilder
// Title SnowflakeIdComponentBuilder
// Description 		雪花ID组件构造器
// Author  			alittlexincan@163.com 								2024/07/22 11:36
// Update  			alittlexincan@163.com 								2024/07/22 11:36
type SnowflakeIdComponentBuilder struct {
	*snowflakeIdComponent
}

// NewSnowflakeIdComponentBuilder
// Title NewSnowflakeIdComponentBuilder
// Description 		创建雪花ID组件构造器
// Author  			alittlexincan@163.com 								2024/07/22 11:36
// Update  			alittlexincan@163.com 								2024/07/22 11:36
// Return    		*SnowflakeIdComponentBuilder    					返回雪花ID组件构造器实例
func NewSnowflakeIdComponentBuilder() *SnowflakeIdComponentBuilder {
	return &SnowflakeIdComponentBuilder{
		snowflakeIdComponent: &snowflakeIdComponent{},
	}
}

// WithLogger
// Title 			WithLogger
// Description 		设置雪花ID组件日志组件
// Author  			alittlexincan@163.com 								2024/07/22 11:36
// Update  			alittlexincan@163.com 								2024/07/22 11:36
// Param    		logger *logging.TraceLogger 						传入雪花ID组件日志组件
// Return    		*SnowflakeIdComponentBuilder    					返回雪花ID组件构造器实例
func (builder *SnowflakeIdComponentBuilder) WithLogger(logger *logging.TraceLogger) *SnowflakeIdComponentBuilder {
	builder.logger = logger
	return builder
}

// WithApplicationConfig
// Title 			WithApplicationConfig
// Description 		设置雪花ID组件系统配置信息
// Author  			alittlexincan@163.com 								2024/07/22 11:36
// Update  			alittlexincan@163.com 								2024/07/22 11:36
// Param    		app *core.Service 									传入系统配置信息
// Return    		*SnowflakeIdComponentBuilder    					返回雪花ID组件构造器实例
func (builder *SnowflakeIdComponentBuilder) WithApplicationConfig(app *types.Service) *SnowflakeIdComponentBuilder {
	nodeId := int64(app.Config.Node)
	if nodeId < 0 || nodeId > 1023 {
		builder.logger.Warn("创建雪花ID组件: 错误, 节点ID范围0-1023")
		builder.nodeId = 1
		return builder
	}
	builder.nodeId = nodeId
	return builder
}

// Build
// Title Build
// Description 		创建雪花ID组件实例
// Author  			alittlexincan@163.com 								2024/07/22 11:36
// Update  			alittlexincan@163.com 								2024/07/22 11:36
// Return    		*snowflake.Node    									返回雪花ID组件实例
func (builder *SnowflakeIdComponentBuilder) Build() *snowflake.Node {
	return builder.configLoad()
}

// configLoad
// Title configLoad
// Description 		加载雪花ID配置信息
// Author  			alittlexincan@163.com 								2024/07/22 11:36
// Update  			alittlexincan@163.com 								2024/07/22 11:36
// Return    		*snowflake.Node    									返回雪花ID组件实例
func (id *snowflakeIdComponent) configLoad() *snowflake.Node {
	id.once.Do(func() {
		tm, _ := time.Parse("2006-01-02 03:04:05", "2025-01-01 00:00:00")
		snowflake.Epoch = tm.UnixNano()
		if instance, err := snowflake.NewNode(id.nodeId); err != nil {
			id.logger.Error("加载雪花配置信息: 错误, 请检查雪花ID配置", zap.Error(err))
		} else {
			id.logger.Info("加载雪花配置信息成功")
			id.instance = instance
		}
	})
	return id.instance
}
